﻿using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;



namespace Crocodile.AbstractLanguage.Coding
{
    /// <summary>
    /// File generating service.
    /// </summary>
    public class CodeFile 
    {
        private int DefaultIndentOffset;


        private StringBuilder Buf = new StringBuilder(65536);

        private readonly Stack<string> Indents = new Stack<string>();



        public CodeFile(int defaultIndentOffset = 4)
        {
            DefaultIndentOffset = defaultIndentOffset;
            Indents.Push(string.Empty);
        }


        private string CurrIndentStr { get { return Indents.Peek(); } }


        public void Indent()
        {
            string indentAddition = new string(' ', DefaultIndentOffset);
            Indent(indentAddition);
        }


        public void Indent(string indentAddition)
        {
            string newIndentStr = CurrIndentStr + indentAddition;
            Indents.Push(newIndentStr);
        }


        public void IndentWithBrace()
        {
            Line("{");
            Indent();
        }


        public void Unindent()
        {
            Debug.Assert(Indents.Count >= 2);
            Indents.Pop();
        }


        public void UnindentWithBrace()
        {
            Unindent();
            Line("}");
        }



        public void Line(params string[] phrases)
        {
            Buf.Append(CurrIndentStr);
            foreach (string str in phrases)
                Buf.Append(str);
            Buf.Append('\n');
        }


        public void Line(string line)
        {
            Buf.Append(CurrIndentStr).Append(line).Append('\n');
        }


        public void EmptyLine()
        {
            Buf.Append(CurrIndentStr).Append('\n');
        }



        public string GetText()
        {
            return Buf.ToString();
        }


        public void Print(TextWriter writer)
        {
            writer.Write(Buf);
        }


    }
}
